// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: xguo

#pragma once

#include <chrono>
#include <cstdint>
#include <functional>
#include <iostream>
#include <string>

#include <boost/date_time/posix_time/posix_time.hpp>

namespace coin2::exchange::base::symbology {

using Datetime = boost::posix_time::ptime;

inline bool IsDateStr(const std::string& date_time_str) {
  if (date_time_str.size() != 8) {
    return false;
  }

  bool all_digit = std::all_of(date_time_str.begin(), date_time_str.end(), ::isdigit);
  if (!all_digit) {
    return false;
  }
  auto year = std::stoi(date_time_str.substr(0, 4));
  if (year < 1970 || year > 3000) {
    return false;
  }

  auto month = std::stoi(date_time_str.substr(4, 2));
  if (month <= 0 || month > 12) {
    return false;
  }

  auto day = std::stoi(date_time_str.substr(6, 2));
  return !(day <= 0 || month > 31);
}

inline std::string ToDateStr(int64_t timestamp) {
  using namespace boost::posix_time;
  auto date = from_time_t(::ceil(timestamp / 1e9)).date();
  std::stringstream ss;
  ss << date.year() << std::setw(2) << std::setfill('0') << static_cast<int>(date.month())
     << std::setw(2) << std::setfill('0') << date.day();
  return ss.str();
}

inline int64_t DatetimeToTimestamp(const boost::posix_time::ptime& date_time) {
  using namespace boost::posix_time;
  using namespace boost::gregorian;
  static ptime epoch(date(1970, 1, 1));
  return (date_time - epoch).total_seconds() * 1e9;
}

}  // namespace coin2::exchange::base::symbology
